{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<re.Match object; span=(0, 5), match='hello'>\n",
      "hello\n",
      "(0, 5)\n",
      "['__class__', '__class_getitem__', '__copy__', '__deepcopy__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'end', 'endpos', 'expand', 'group', 'groupdict', 'groups', 'lastgroup', 'lastindex', 'pos', 're', 'regs', 'span', 'start', 'string']\n",
      "0\n",
      "5\n",
      "hello hello world\n",
      "{}\n",
      "()\n"
     ]
    }
   ],
   "source": [
    "import re\n",
    "pattern = \"hello\"\n",
    "str = \"hello hello world\"\n",
    "v =re.match(pattern, str)\n",
    "print(v)\n",
    "print(v.group())\n",
    "print(v.span())\n",
    "print(dir(v))\n",
    "print(v.start())\n",
    "print(v.end())\n",
    "print(v.string)\n",
    "print(v.groupdict())\n",
    "print(v.groups())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<re.Match object; span=(0, 1), match='8'>\n",
      "<re.Match object; span=(0, 1), match='8'>\n"
     ]
    }
   ],
   "source": [
    "pattern = \".\"\n",
    "s = \"A\"\n",
    "s = \"a\"\n",
    "s = \"8\"\n",
    "# s = \"_\"\n",
    "print(re.match(pattern, s))\n",
    "print(re.match(pattern, s, re.I))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<re.Match object; span=(0, 15), match='123456789012345'>\n"
     ]
    }
   ],
   "source": [
    "pattern = \"1\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d\"\n",
    "print(re.match(pattern, \"123456789012345\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<re.Match object; span=(0, 4), match='1345'>\n"
     ]
    }
   ],
   "source": [
    "pattern = \"1[35789]\\d{2}\"  # 匹配手机号\n",
    "s = \"13456788789\"\n",
    "v = re.match(pattern, s)\n",
    "print(v)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<re.Match object; span=(0, 13), match='0411-84305092'>\n"
     ]
    }
   ],
   "source": [
    "pattern = \"\\d*[-]\\d*\"\n",
    "s = \"0411-84305092\"\n",
    "print(re.match(pattern, s))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<re.Match object; span=(0, 1), match='1'>\n"
     ]
    }
   ],
   "source": [
    "pattern = \"\\d?\"  # 0 次或多次\n",
    "s = \"123abc\"\n",
    "# s = \"abc\"\n",
    "# 这时候不是 None 而是'',因为 abc 前面默认有空\n",
    "v = re.match(pattern, s)\n",
    "print(v)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<re.Match object; span=(0, 3), match='Hel'>\n"
     ]
    }
   ],
   "source": [
    "pattern = \"[A-Z][a-z]*\"\n",
    "s = \"Hel1lo F\"\n",
    "print(re.match(pattern, s))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "None\n"
     ]
    }
   ],
   "source": [
    "pattern = \"[1-9]\\d?\"\n",
    "s = \"1\"\n",
    "s = \"55\"\n",
    "s = \"99\"\n",
    "s = \"199\"\n",
    "s = \"0\"\n",
    "v = re.match(pattern, s)\n",
    "print(v)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "匹配的结果2: c:\\a\\b\n",
      "使用 Python r前缀后匹配的结果: c:\\a\\b\n"
     ]
    }
   ],
   "source": [
    "s = \"c:\\\\a\\\\b\\\\c\"\n",
    "m = re.match(\"c:\\\\a\\\\b\", s)\n",
    "if m is not None:\n",
    "    print(\"匹配的结果 1:\", m.group())\n",
    "\n",
    "m = re.match(\"c:\\\\\\\\a\\\\\\\\b\", s)\n",
    "if m is not None:\n",
    "    print(\"匹配的结果2:\", m.group())\n",
    "\n",
    "# 使用Python中的r前缀\n",
    "rm = re.match(r\"c:\\\\a\\\\b\", s)\n",
    "if m is not None:\n",
    "    print(\"使用 Python r前缀后匹配的结果:\", m.group())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<re.Match object; span=(0, 12), match='hello python'>\n"
     ]
    }
   ],
   "source": [
    "s = \"hello world\"\n",
    "s = \"hello python\"\n",
    "pattern = r\"^hello.*\"\n",
    "o = re.match(pattern, s)\n",
    "print(o)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<re.Match object; span=(0, 14), match='123 abr abr ab'>\n"
     ]
    }
   ],
   "source": [
    "\"\"\"单词边界\"\"\"\n",
    "import re\n",
    "pattern = r\".*\\bab\"\n",
    "s = \"123 abr abr abrr\"\n",
    "print(re.match(pattern, s))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "None\n",
      "None\n"
     ]
    }
   ],
   "source": [
    "pattern = r\".*\\Bab\"  # ab 不为左边界\n",
    "v = re.match(pattern, \"123 abr\")\n",
    "print(v)\n",
    "\n",
    "\n",
    "pattern = r\".*ab\\B\"  # ab 不为右边界\n",
    "v = re.match(pattern, \"wab\")\n",
    "print(v)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<re.Match object; span=(5, 8), match='abc'>\n",
      "abc\n",
      "<re.Match object; span=(0, 7), match='bcde ab'>\n"
     ]
    }
   ],
   "source": [
    "import re\n",
    "s = \"bcde abcfg\"\n",
    "m = re.search(\"abc\", s)\n",
    "print(m)\n",
    "print(m.group())\n",
    "\n",
    "pattern = r\".*\\bab\"\n",
    "o = re.search(pattern, s)\n",
    "print(o)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<re.Match object; span=(0, 1), match='x'>\n",
      "<re.Match object; span=(0, 1), match='y'>\n"
     ]
    }
   ],
   "source": [
    "import re\n",
    "pattern = r\"[xyz]\"\n",
    "print(re.search(pattern, \"x\"))\n",
    "\n",
    "pattern = r\"x|y|z\"\n",
    "print(re.search(pattern, \"y\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<re.Match object; span=(0, 12), match='0411-8461562'>\n",
      "0411-8461562\n",
      "0411\n",
      "8461562\n",
      "('0411', '8461562')\n",
      "0411\n",
      "8461562\n"
     ]
    }
   ],
   "source": [
    "# group\n",
    "import re\n",
    "pattern = r\"(\\d+)-(\\d{5,8}$)\"\n",
    "pattern = r\"(\\d{3,4})-([1-9]\\d{4,7}$)\"\n",
    "s = \"0411-8461562\"\n",
    "o = re.match(pattern, s)\n",
    "print(o)\n",
    "print(o.group())\n",
    "print(o.group(1))\n",
    "print(o.group(2))\n",
    "print(o.groups())\n",
    "print(o.groups()[0])\n",
    "print(o.groups()[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<re.Match object; span=(0, 32), match='<html><title>我是标题</title></html>'>\n",
      "('html', 'title')\n"
     ]
    }
   ],
   "source": [
    "# 匹配出网页标签内的数据\n",
    "s = \"<html><title>我是标题</title></html>\"\n",
    "# 优化前\n",
    "# pattern = r'<.+><.+>.+</.+></.+>'\n",
    "# 优化后 可以使用分组 \\2 表示引用第 2 个分组 \\1 表示引用第 1 个分组\n",
    "pattern = r\"<(.+)><(.+)>.+</\\2></\\1>\"\n",
    "v = re.match(pattern, s)\n",
    "print(v)\n",
    "print(v.groups())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<re.Match object; span=(0, 31), match='<html><title>我是标题</head></body>'>\n"
     ]
    }
   ],
   "source": [
    "pattern = r\"<.+><.+>.+</.+></.+>\"\n",
    "s = \"<html><title>我是标题</title></html>\"\n",
    "s = \"<html><title>我是标题</head></body>\"  # 错误的语法\n",
    "print(re.match(pattern, s))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "None\n"
     ]
    }
   ],
   "source": [
    "pattern = r\"<(.+)><(.+)>.+</\\2></\\1>\"\n",
    "s = \"<html><title>我是标题</head></body>\"  # 错误的语法\n",
    "print(re.match(pattern, s))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "电话号码是:   2004-959-559 \n",
      "电话号码是 :  2004959559\n",
      "('2004959559', 16)\n",
      "替换的结果: 2004959559\n",
      "替换的次数: 16\n"
     ]
    }
   ],
   "source": [
    "import re\n",
    "\n",
    "phone = \"2004-959-559 #  这是一个国外电话号码\"\n",
    "# 删除字符串中的Python注释\n",
    "num = re.sub(r\"#.*$\", \"\", phone)\n",
    "print(\"电话号码是:  \", num)\n",
    "# 删除非数字(-)的字符串\n",
    "num = re.sub(r\"\\D\", \"\", phone)\n",
    "print(\"电话号码是 : \", num)\n",
    "# subn 函数的使用\n",
    "result = re.subn(r\"\\D\", \"\", phone)\n",
    "print(result)\n",
    "print(\"替换的结果:\", result[0])\n",
    "print(\"替换的次数:\", result[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "first123\n",
      "None\n"
     ]
    }
   ],
   "source": [
    "import re\n",
    "\n",
    "s = \"first123 line\"\n",
    "regex = re.compile(r\"\\w+\")  # 匹配至少一个字母或数字\n",
    "m = regex.match(s)\n",
    "print(m.group())\n",
    "# s 的开头是\"f\",  但正则中限制了开始为i 所以匹配失败\n",
    "regex = re.compile(\"^i\\w+\")\n",
    "print(regex.match(s))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['first', '1', 'second', '2', 'third', '3']\n"
     ]
    }
   ],
   "source": [
    "pattern = r\"\\w+\"\n",
    "s = \"first 1 second 2 third 3\"\n",
    "o = re.findall(pattern, s)\n",
    "print(o)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<callable_iterator object at 0x7facf4698550>\n",
      "first\n",
      "1\n",
      "second\n",
      "2\n",
      "third\n",
      "3\n"
     ]
    }
   ],
   "source": [
    "pattern = r\"\\w+\"\n",
    "s = \"first 1 second 2 third 3\"\n",
    "o = re.finditer(pattern, s)\n",
    "print(o)\n",
    "for i in o:\n",
    "    print(i.group())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['first ', ' second ', ' third ', '']\n",
      "['first ', ' second 22 third 33']\n"
     ]
    }
   ],
   "source": [
    "import re\n",
    "\n",
    "s = \"first 11 second 22 third 33\"\n",
    "# 按数字切分\n",
    "print(re.split(r\"\\d+\", s))\n",
    "# maxsplit 参数限定分隔的次数,这里限定为 1,也就是只分隔一次\n",
    "print(re.split(r\"\\d+\", s, 1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "----------贪婪模式---------\n",
      "This is my tel:13\n",
      "3-1234-1234\n",
      "----------非贪婪模式---------\n",
      "This is my tel:\n",
      "133-1234-1234\n"
     ]
    }
   ],
   "source": [
    "v = re.match(r\"(.+)(\\d+-\\d+-\\d+)\", \"This is my tel:133-1234-1234\")\n",
    "print(\"----------贪婪模式---------\")\n",
    "print(v.group(1))\n",
    "print(v.group(2))\n",
    "print(\"----------非贪婪模式---------\")\n",
    "v = re.match(r\"(.+?)(\\d+-\\d+-\\d+)\", \"This is my tel:133-1234-1234\")\n",
    "print(v.group(1))\n",
    "print(v.group(2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "贪婪模式\n",
      "123\n",
      "非贪婪模式\n",
      "1\n"
     ]
    }
   ],
   "source": [
    "print(\"贪婪模式\")\n",
    "v = re.match(r\"abc(\\d+)\", \"abc123\")\n",
    "print(v.group(1))\n",
    "# 非贪婪模式\n",
    "print(\"非贪婪模式\")\n",
    "v = re.match(r\"abc(\\d+?)\", \"abc123\")\n",
    "print(v.group(1))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "base",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
